package com.dragon.common.utils.email;

import jakarta.activation.DataSource;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;

/**
 * JavaMailSender工具类
 *
 * @author dragon
 * @version 1.0
 * @date 2024/7/24 17:14
 */
public class JavaMailSenderUtils {

    /**
     * 邮件发送人
     */
    private final String senderMail;
    /**
     * JavaMailSender
     */
    private final JavaMailSender javaMailSender;


    /**
     * 构造方法
     *
     * @param mailHost 邮件服务器地址
     * @param username 邮件服务器用户名
     * @param password 邮件服务器密码
     */
    public JavaMailSenderUtils(String mailHost, String username, String password) {
        this(mailHost, username, password, null);
    }

    /**
     * 构造方法
     *
     * @param mailHost 邮件服务器地址
     * @param username 邮件服务器用户名
     * @param password 邮件服务器密码
     * @param port     邮件服务器端口
     */
    public JavaMailSenderUtils(String mailHost, String username, String password, Integer port) {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

        mailSender.setHost(mailHost);
        // 根据你的SMTP服务器可能需要更改
        if (port != null) {
            mailSender.setPort(port);
        }

        mailSender.setUsername(username);
        mailSender.setPassword(password);
        mailSender.setDefaultEncoding(StandardCharsets.UTF_8.name());

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");
        // 可选，用于调试，显示发送邮件的详细信息
        // props.put("mail.debug", "true");

        senderMail = username;
        javaMailSender = mailSender;
    }

    /**
     * 发送电子邮件
     *
     * @param receiveEmail 邮件接收人
     * @param subject      邮件主题不能为空
     * @param content      邮件内容不能为空
     * @throws MessagingException 发送异常
     */
    public void mimeMail(String receiveEmail,
                         String subject,
                         String content) throws MessagingException {
        mimeMail(new ArrayList<>(Collections.singleton(receiveEmail)), subject, content, null, null);
    }

    /**
     * 发送电子邮件
     *
     * @param receiveEmails 邮件接收人
     * @param subject       邮件主题不能为空
     * @param content       邮件内容不能为空
     * @throws MessagingException 发送异常
     */
    public void mimeMail(Collection<String> receiveEmails,
                         String subject,
                         String content) throws MessagingException {
        mimeMail(receiveEmails, subject, content, null, null);
    }

    /**
     * 发送电子邮件
     *
     * @param receiveEmail 邮件接收人
     * @param subject      邮件主题不能为空
     * @param content      邮件内容不能为空
     * @param attachments  附件集合
     * @throws MessagingException 发送异常
     */
    public void mimeMail(String receiveEmail,
                         String subject,
                         String content,
                         Map<String, Object> attachments) throws MessagingException {
        mimeMail(new ArrayList<>(Collections.singleton(receiveEmail)), subject, content, attachments, null);
    }

    /**
     * 发送电子邮件
     *
     * @param receiveEmails 邮件接收人
     * @param subject       邮件主题不能为空
     * @param content       邮件内容不能为空
     * @param attachments   附件集合
     * @throws MessagingException 发送异常
     */
    public void mimeMail(Collection<String> receiveEmails,
                         String subject,
                         String content,
                         Map<String, Object> attachments) throws MessagingException {
        mimeMail(receiveEmails, subject, content, attachments, null);
    }

    /**
     * 发送电子邮件
     *
     * @param receiveEmail 邮件接收人
     * @param subject      邮件主题不能为空
     * @param content      邮件内容不能为空
     * @param attachments  附件集合
     * @throws MessagingException 发送异常
     */
    public void mimeMail(String receiveEmail,
                         String subject,
                         String content,
                         Map<String, Object> attachments,
                         Map<String, Object> inLines) throws MessagingException {
        mimeMail(new ArrayList<>(Collections.singleton(receiveEmail)), subject, content, attachments, inLines);
    }

    /**
     * 发送电子邮件
     *
     * @param receiveEmails 邮件接收人
     * @param subject       邮件主题不能为空
     * @param content       邮件内容不能为空
     * @param attachments   附件集合
     * @param inLines       静态资源集合
     * @throws MessagingException 发送异常
     */
    public void mimeMail(Collection<String> receiveEmails,
                         String subject,
                         String content,
                         Map<String, Object> attachments,
                         Map<String, Object> inLines) throws MessagingException {
        // 参数校验
        if (StringUtils.isBlank(senderMail)) {
            throw new RuntimeException("邮件发送人不能为空");
        }
        if (CollectionUtils.isEmpty(receiveEmails)) {
            throw new RuntimeException("邮件接收人不能为空");
        }
        if (StringUtils.isBlank(subject)) {
            throw new RuntimeException("邮件主题不能为空");
        }
        if (StringUtils.isBlank(content)) {
            throw new RuntimeException("邮件内容不能为空");
        }

        List<String> emails = new ArrayList<>(receiveEmails);

        System.out.println("================= 发送邮件 开始 =================");
        System.out.println("邮件发送人：" + senderMail);
        System.out.println("邮件接收人：" + emails);
        System.out.println("邮件主题：" + subject);
        System.out.println("邮件内容：" + content);

        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);

        // 邮件发送人
        mimeMessageHelper.setFrom(senderMail);
        // 邮件接收人
        String receiveEmail = emails.remove(0);
        mimeMessageHelper.setTo(receiveEmail);
        // 邮件主题
        mimeMessageHelper.setSubject(subject);
        // 邮件内容
        mimeMessageHelper.setText(content, true);
        // 抄送
        if (!emails.isEmpty()) {
            mimeMessageHelper.setCc(emails.toArray(String[]::new));
        }
        // 附件
        if (Objects.nonNull(attachments) && !attachments.isEmpty()) {
            for (Map.Entry<String, Object> entry : attachments.entrySet()) {
                if (entry.getValue() instanceof DataSource) {
                    mimeMessageHelper.addAttachment(entry.getKey(), (DataSource) entry.getValue());
                }
                if (entry.getValue() instanceof File) {
                    mimeMessageHelper.addAttachment(entry.getKey(), (File) entry.getValue());
                }
                if (entry.getValue() instanceof InputStreamSource) {
                    mimeMessageHelper.addAttachment(entry.getKey(), (InputStreamSource) entry.getValue());
                }
            }
        }
        // 静态资源
        if (Objects.nonNull(inLines) && !inLines.isEmpty()) {
            for (Map.Entry<String, Object> entry : inLines.entrySet()) {
                if (entry.getValue() instanceof DataSource) {
                    mimeMessageHelper.addInline(entry.getKey(), (DataSource) entry.getValue());
                }
                if (entry.getValue() instanceof File) {
                    mimeMessageHelper.addInline(entry.getKey(), (File) entry.getValue());
                }
                if (entry.getValue() instanceof org.springframework.core.io.Resource) {
                    mimeMessageHelper.addInline(entry.getKey(), (org.springframework.core.io.Resource) entry.getValue());
                }
            }
        }

        // 发送邮件
        javaMailSender.send(mimeMessage);

        System.out.println("================= 发送邮件 结束 =================");
    }

}
